#include <iostream>

using namespace std;

void test01() {
    int blue = 10;

    // 给 blue 的空间取别名叫做 yui
    int &yui = blue;

    // 变量 yui 更改值时, 等效于 blue 更改值
    yui = 100;
    cout << "blue = " << blue << endl;
    cout << "yui = " << yui << endl;

    // 上方的引用和指针类似
    int *p = &blue;
    *p = 1000;
    cout << "blue = " << blue << endl;
    cout << "*p = " << *p << endl;

    cout << endl;
}

void test02() {
    // 1.引用创建时, 必须初始化
    int blue = 10;

    // 非法创建
    // int &yui;

    // 正常创建
    int &yui = blue;

    // 2.引用一旦初始化, 就不能改变它的指向
    int value = 100;

    // 赋值操作
    yui = value;

    // 非法操作
    // &yui = value;

    // 3.引用的地址和源变量地址一样
    cout << "&blue  = " << &blue << endl;
    cout << "&yui = " << &yui << endl;

    // 4.引用必须引用一块合法的内存空间

    cout << endl;
}

void printfArray(int length, int *array) {
    int *p = array;
    for (int i = 0; i < length; ++i) {
        cout << p[i] << " ";
    }
    cout << endl;
}

void test03() {
    // 数组创建引用的方法
    int length = 10;
    int array0[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

    // 1.定义数组类型, 在创建引用
    typedef int(MY_ARRAY1)[length];
    MY_ARRAY1 &array1 = reinterpret_cast<MY_ARRAY1 &>(array0);

    // 2.定义引用数组类型, 在创建引用
    typedef int(&MY_ARRAY2)[length];
    MY_ARRAY2 &array2 = reinterpret_cast<MY_ARRAY2>(array0);

    // 3.直接创建引用 创建失败???
    // int (&array3)[length] = array;

    printfArray(length, reinterpret_cast<int *>(&array0));
    printfArray(length, reinterpret_cast<int *>(&array1));
    printfArray(length, reinterpret_cast<int *>(&array2));

    cout << endl;
}

void test04() {
    int blue = 10;

    // 指针 p1 指向 blue 变量的地址
    int *p1 = &blue;

    // 创建指针引用
    // 给指针 p1 取别名为 p2
    int *(&p2) = p1;

    // 操作指针 p1 等效于操作变量 blue
    *p1 = 100;
    cout << "blue = " << blue << endl;
    cout << "*p1 = " << *p1 << endl;

    // 操作指针 p2 等效于操作指针 p1
    *p2 = 200;
    cout << "blue = " << blue << endl;
    cout << "*p2 = " << *p2 << endl;

    cout << endl;
}

void test05() {
    int blue = 10;

    int &yui = blue; // 等效于 int *const yui = &blue; 这也是为什么引用必须初始化

    yui = 100; // 等效于 *yui = 100;

    // 上述操作都是编译器帮我们做的

    // 总结
    // 1.引用就是给变量取别名
    // 2.引用的本质就是 常指针(XXX * const)
    // 3.指针有多级指针, 而引用只有一级
}

int &function() {
    int a = 100;

    int &b = a;

    return b;
}

void test06() {
    int &a = function();

    cout << a;
}

int main() {
    test01();

    test02();

    test03();

    test04();

    test05();

    test06();
}